<template>
    <view>
        <!-- 显示标签 -->
        <!-- #ifdef MP-WEIXIN -->
        <view class="py-cascader">
            <!-- #endif -->
            <u-tag v-if="!cascaderText || cascaderText == ''" text="选择级联" @click="cascaderShow = true;"></u-tag>
            <u-tag v-else :text="cascaderText" plain @click="cascaderShow = true;"></u-tag>
            <!-- #ifdef MP-WEIXIN -->
        </view>
        <!-- #endif -->

        <!-- 多级联动选择器 -->
        <view>
            <u-picker :show="cascaderShow" ref="cascaderPicker" :columns="cascaderPickerColumns"
                :defaultIndex="cascaderDefaultIndex" :keyName="labelName" closeOnClickOverlay
                @close="cascaderShow = false;" @cancel="cascaderShow = false;" @change="handleCascaderPickerChange"
                @confirm="handleCascaderPickerConfirm" :showToolbar="showToolbar" :title="title"
                :itemHeight="itemHeight" :cancelText="cancelText" :confirmText="confirmText" :cancelColor="cancelColor"
                :confirmColor="confirmColor" :visibleItemCount="visibleItemCount"></u-picker>
        </view>
    </view>
</template>
<!-- 
    1.组件对应element-ui中的el-cascader组件，使用方法完全一致，但是有些属性没有完成功能。
    目前已完成功能的属性：
	v-model：绑定使用此方式，不要使用value传值
	options：功能与el-cascader一致
	props：只支持设置value、label、children三个属性
    
    2.其他属性对应u-picker的样式属性，具体可以看props中配置说明。
 -->
<script>
    export default {
        // 微信小程序解除样式隔离
        // #ifdef MP-WEIXIN
        options: {
            styleIsolation: "shared"
        },
        // #endif
        name: "PyCascader",
        props: {
            // el-cascader组件属性设置开始
            // 绑定值
            value: {},
            // 级联数组
            options: Array,
            // 级联属性名称
            props: {
                type: Object,
                default() {
                    return {
                        value: "value",
                        label: "label",
                        children: "children"
                    }
                }
            },
            //el-cascader组件属性设置结束

            // u-picker组件属性设置开始
            // 是否展示顶部的操作栏
            showToolbar: {
                type: Boolean,
                default: uni.$u.props.picker.showToolbar
            },
            // 顶部标题
            title: {
                type: String,
                default: uni.$u.props.picker.title
            },
            // 各列中，单个选项的高度
            itemHeight: {
                type: [String, Number],
                default: uni.$u.props.picker.itemHeight
            },
            // 取消按钮的文字
            cancelText: {
                type: String,
                default: uni.$u.props.picker.cancelText
            },
            // 确认按钮的文字
            confirmText: {
                type: String,
                default: uni.$u.props.picker.confirmText
            },
            // 取消按钮的颜色
            cancelColor: {
                type: String,
                default: uni.$u.props.picker.cancelColor
            },
            // 确认按钮的颜色
            confirmColor: {
                type: String,
                default: uni.$u.props.picker.confirmColor
            },
            // 每列中可见选项的数量
            visibleItemCount: {
                type: [String, Number],
                default: uni.$u.props.picker.visibleItemCount
            }
        },
        data() {
            return {
                // 值名称
                valueName: this.props.value,
                // 标签名称
                labelName: this.props.label,
                // 子节点名称
                childrenName: this.props.children,

                // 当前选择值列表
                currentSelectValueList: this.value,

                // 级联选择器显示的列信息
                cascaderPickerColumns: [],

                // 级联选择器是否显示
                cascaderShow: false,

                // 级联选择器默认索引
                cascaderDefaultIndex: [],

                // 级联标签内容
                cascaderText: undefined


            }
        },
        created() {
            // 如果没有默认值，将所有层第一个值设为初始值
            if (!this.value) {
                this.currentSelectValueList = [];
                // 获取所有层一个对象的值列表
                this.getFirstChildrenValueList(this.options, this.valueName, this.childrenName);
            }

            // 获取级联选择器显示的列信息
            this.getCascaderPickerColumns();

        },
        watch: {
            currentSelectValueList: function (newVal, oldVal) {
                this.$emit("input", newVal);
            },

            value: function (newVal, oldVal) {
                // 表单重置时调用
                if (!newVal) {
                    this.currentSelectValueList = [];
                    this.cascaderPickerColumns = [];
                    // 获取所有层一个对象的值列表
                    this.getFirstChildrenValueList(this.options, this.valueName, this.childrenName);
                    // 获取级联选择器显示的列信息
                    this.getCascaderPickerColumns();
                }
            }
        },
        methods: {
            // 获取每层第一个数值
            getFirstChildrenValueList(data, valueName, childrenName) {
                if (data && data.length && data.length > 0) {
                    let firstData = data[0];
                    let firstValue = firstData && firstData[valueName];
                    this.currentSelectValueList.push(firstValue);
                    if (Object.hasOwnProperty.call(firstData, childrenName)) {
                        this.getFirstChildrenValueList(firstData[childrenName], valueName, childrenName);
                    }

                }

            },

            // 获取每一层第一个数据
            getFirstChildrenList(data, childrenName, list) {
                if (data && data.length && data.length > 0) {
                    list.push(data);
                    let firstData = data[0];
                    if (Object.hasOwnProperty.call(firstData, childrenName)) {
                        this.getFirstChildrenList(firstData[childrenName], childrenName, list);
                    }
                }
            },

            // 获取级联选择器显示的列信息
            getCascaderPickerColumns() {
                let options = this.options;
                if (options && options.length && options.length > 0) {
                    let currentSelectValueList = this.currentSelectValueList;
                    let valueName = this.valueName;
                    let childrenName = this.childrenName;
                    let labelName = this.labelName;
                    this.cascaderText = "";
                    this.loopSearchCascaderPickerColumns(options, 0, currentSelectValueList, valueName, childrenName, labelName);
                }

            },

            // 循环查找级联选择器列信息
            loopSearchCascaderPickerColumns(options, i, currentSelectValueList, valueName, childrenName, labelName) {
                this.cascaderPickerColumns.push(options);
                if (i < currentSelectValueList.length) {
                    let currentValue = currentSelectValueList[i];
                    for (let index = 0; index < options.length; index++) {
                        const element = options[index];

                        if (element && element[valueName] && element[valueName] == currentValue) {
                            this.cascaderDefaultIndex.push(index);

                            let label = element[labelName];
                            if (label) {
                                if (this.cascaderText == "") {
                                    this.cascaderText = label;
                                } else {
                                    this.cascaderText += "/" + label;
                                }
                            }

                            if (element[childrenName]) {
                                this.loopSearchCascaderPickerColumns(element[childrenName], ++i, currentSelectValueList, valueName, childrenName, labelName);
                            }
                            break;
                        }

                    }
                }
            },

            // 处理级联选择器改变
            handleCascaderPickerChange(e) {
                const {
                    columnIndex, // 当前列索引
                    value,  // 当前所有层的值组成的数组
                    values, // 所有层的组成的数据
                    index,  // 变动值在列的索引
                    indexs, // 当前所有层的索引组成的数据
                    // 微信小程序无法将picker实例传出来，只能通过ref操作
                    picker = this.$refs.cascaderPicker
                } = e;

                let childrenName = this.childrenName;
                let labelName = this.labelName;
                let valueName = this.valueName;

                // 当前所有层数
                let columnCount = value.length;
                if (columnIndex != columnCount - 1) {
                    let cascaderPickerColumns = this.cascaderPickerColumns;
                    // 当前层对象
                    let currentObj = value[columnIndex];

                    let toEmptyIndex = columnIndex + 1;
                    if (Object.hasOwnProperty.call(currentObj, childrenName)) {
                        let nextColumnIndex = columnIndex + 1;
                        let list = [];
                        this.getFirstChildrenList(currentObj[childrenName], childrenName, list);
                        for (let i = 0; i < list.length; i++) {
                            const element = list[i];
                            picker.setColumnValues(nextColumnIndex + i, element);
                        }
                        toEmptyIndex = nextColumnIndex + list.length;

                    }

                    // 如果列更多，对于部分置空
                    if (toEmptyIndex < columnCount) {
                        for (let index = toEmptyIndex; index < columnCount; index++) {
                            picker.setColumnValues(index, []);
                        }
                    }

                }

            },

            // 处理处理级联选择器确定点击
            handleCascaderPickerConfirm(e) {
                // 关闭弹窗
                this.cascaderShow = false;
                const {
                    columnIndex, // 当前列索引
                    value,  // 当前所有层的值组成的数组
                    values, // 所有层的组成的数据
                    index,  // 变动值在列的索引
                    indexs // 当前所有层的索引组成的数据
                } = e;

                let valueName = this.valueName;
                let labelName = this.labelName;
                // 将值和显示标签置空
                this.currentSelectValueList = [];
                this.cascaderText = "";
                value.forEach(element => {
                    if (element) {
                        this.currentSelectValueList.push(element[valueName]);
                        if (this.cascaderText == "") {
                            this.cascaderText = element[labelName];
                        } else {
                            this.cascaderText += "/" + element[labelName];
                        }
                    }

                });



            },
        },
    }
</script>
<style lang="css" scoped>
    /* 微信小程序样式设置 */
    /* #ifdef MP-WEIXIN */
    /* 宽度自适应内容 */
    .py-cascader {
        display: flex;
        width: fit-content;
    }

    /* #endif */
</style>